/*
 * @FileName: [AESCryptor.java] 
 * @Package com.bcinfo.upp.util 
 * 
 * 
 * Copyright (c) 2011-2015 BCINFO Technology Limited Com.
 * All rights reserved.
 * 
 * This software is the confidential and proprietary 
 * information of BCINFO Technology Limited Company
 * ("Confidential Information"). You shall not disclose 
 * such Confidential Information and shall use it only
 * in accordance with the terms of the contract agreement 
 * you entered into with RKY.
 * 
 * $Rev: 1014 $
 * $LastChangedDate: 2014-01-03 09:45:23 +0800 (Fri, 03 Jan 2014) $
 * $LastChangedBy: xusp $
 * 
 * @category bcinfo-upp
 * @version 1.1
 * @author $Author: xusp $
 *
 * Change History:[Formatter: author date description] <br/>
 * 1
 * 2
 * 3
*/

package com.bcinfo.iccard.util;

import java.io.UnsupportedEncodingException;
import java.security.InvalidKeyException;
import java.security.Key;
import java.security.NoSuchAlgorithmException;
import java.security.SecureRandom;

import javax.crypto.BadPaddingException;
import javax.crypto.Cipher;
import javax.crypto.IllegalBlockSizeException;
import javax.crypto.KeyGenerator;
import javax.crypto.NoSuchPaddingException;

import org.apache.commons.codec.binary.Base64;

import com.bcinfo.iccard.log.Log;
import com.bcinfo.iccard.log.LogFactoryUtil;
import com.bcinfo.iccard.exception.IccardException;

/**
 * 
 * AES加密解密工具类 <br/>
 * <p>Description:<br/>
 *    <p>TODO 提供AES加密解密方法
 *
 * <p>For Examples <br/>
 * <PRE>
 *      //加密
 *      String ming = "upp";
        String t="";
        try
        {
            t = AESCryptor.encrypt(ming);
        } catch (IccardException e)
        {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        System.out.println(t);
        an = t;
        
         
        //解密
        String res = "";
        try
        {
            res = AESCryptor.decrypt(an);
        } catch (IccardException e)
        {
            e.printStackTrace();
        }
 * </PRE>
 * <p>
 */
public class AESCryptor 
{
	public static String staticKey = "bcinfo$;^~+po";
	private static Log _logger=LogFactoryUtil.getLog(AESCryptor.class);
	public static Key key;
	/**
	 * 初始化AESKEY
	 */
	static
	{
		try
		{
			KeyGenerator generator = KeyGenerator.getInstance("AES");		
			SecureRandom secureRandom = SecureRandom.getInstance("SHA1PRNG");
			secureRandom.setSeed(staticKey.getBytes("utf-8"));
			generator.init(128,secureRandom);
			key = generator.generateKey();
		}
		catch(NoSuchAlgorithmException e)
		{
		    if(_logger.isErrorEnabled()){
		        _logger.error(e);
		    }
		    throw new RuntimeException("初始化AESKey失败");
		} catch (UnsupportedEncodingException e)
        {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } 
	}
	/**
	 * 
	 * 获取随机key <br/>
	 * <p>Description: TODO() 
	 * <br/>
	 * <p>Author: wangguangchun<br/>
	 * <p>Date: 2013-4-12-下午02:54:08<br/>
	 * <p>
	 * @param key 指定加密key
	 * @return   
	 *
	 */
	public static Key getKey(String key) 
	{
		try 
		{
			KeyGenerator generator = KeyGenerator.getInstance("AES");
			generator.init(new SecureRandom(key.getBytes("utf-8")));
			return generator.generateKey();
		} 
		catch (NoSuchAlgorithmException e) 
		{
		    if(_logger.isErrorEnabled()){
                _logger.error(e);
            }
			return null;
		} catch (UnsupportedEncodingException e)
		
        {
		    if(_logger.isErrorEnabled()){
                _logger.error(e);
            }
            return null;
        }
	}
	
	/**
	 * 
	 * AES加密 <br/>
	 * <p>Description: TODO(给定字符串进行加密) 
	 * <br/>
	 * <p>Author: wangguangchun<br/>
	 * <p>Date: 2013-4-12-下午02:00:53<br/>
	 * <p>
	 * @param input 输入串
	 * @return   返回加密后的加密串
	 * @throws IccardException 
	 *
	 */
    public static String encrypt(String input) throws IccardException
	{
		byte[] enBytes = null;
		byte[] bytes = null;
		Base64 base64=new Base64();
		try 
		{
			bytes = input.getBytes("utf-8");
			enBytes = encryptBytes(bytes);
			byte[] encryptBytes=base64.encode(enBytes);
			 return new String(encryptBytes,"utf-8");
		} 
		catch(UnsupportedEncodingException e) 
		{
		    if(_logger.isErrorEnabled()){
                _logger.error(e);
            }
		    throw new IccardException("AES加密失败");
		} catch (IccardException e)
        {
            // TODO Auto-generated catch block
            if(_logger.isErrorEnabled()){
                _logger.error(e);
            }
            throw new IccardException("AES加密失败");
        }
	}
	
    
    /**
     * 
     * AES解密 <br/>
     * <p>Description: TODO(将给定的字符串进行AES解密) 
     * <br/>
     * <p>Author: wangguangchun<br/>
     * <p>Date: 2013-4-12-下午02:05:07<br/>
     * <p>
     * @param input 待解密字符串
     * @return 解密后的明文
     * @throws IccardException   
     *
     */
    public static String decrypt(String input) throws IccardException
	{
        byte[] bytes=null;
        byte[] enBytes = null;
		Base64 base64=new Base64();
		try
        {
			enBytes = base64.decode(input.getBytes("utf-8"));
			bytes = decryptBytes(enBytes);
            return new String(bytes,"utf-8");
        } catch (UnsupportedEncodingException e)
        {
            if(_logger.isErrorEnabled()){
                _logger.error(e);
            }
            throw new IccardException("AES解密失败");
        }
	}
	/**
	 * 
	 * 按字节数组进行解密 <br/>
	 * <p>Description: TODO(提供按字节数组解密) 
	 * <br/>
	 * <p>Author: wangguangchun<br/>
	 * <p>Date: 2013-4-12-下午02:54:49<br/>
	 * <p>
	 * @param bytes 待解密数组
	 * @return 解密后的字节数组
	 * @throws IccardException   
	 *
	 */
	public static byte[] decryptBytes(byte[] bytes) throws IccardException
	{
		byte[] retVal = null;
		Cipher cipher = null;
        try
        {
            cipher = Cipher.getInstance("AES");
            cipher.init(Cipher.DECRYPT_MODE, key);
            retVal = cipher.doFinal(bytes);
        } catch (NoSuchAlgorithmException e)
        {
            if(_logger.isErrorEnabled()){
                _logger.error(e);
            }
            throw new IccardException(e);
        } catch (NoSuchPaddingException e)
        {
            if(_logger.isErrorEnabled()){
                _logger.error(e);
            }
            throw new IccardException(e);
        } catch (InvalidKeyException e)
        {
            if(_logger.isErrorEnabled()){
                _logger.error(e);
            }
            throw new IccardException(e);
        } catch (IllegalBlockSizeException e)
        {
            if(_logger.isErrorEnabled()){
                _logger.error(e);
            }
            throw new IccardException(e);
        } catch (BadPaddingException e)
        {
            if(_logger.isErrorEnabled()){
                _logger.error(e);
            }
            throw new IccardException(e);
        }
       
        return retVal;
		
	}
	
	/**
	 * 将字节数组加密
	 *  <br/>
	 * <p>Description: TODO(将字节数组加密) 
	 * <br/>
	 * <p>Author: wangguangchun<br/>
	 * <p>Date: 2013-4-12-下午02:55:51<br/>
	 * <p>
	 * @param bytes 待加密字节数组
	 * @return 返回加密后字节数组
	 * @throws IccardException   
	 *
	 */
	private static byte[] encryptBytes(byte[] bytes) throws IccardException
	{
		byte[] retVal = null;
		Cipher cipher = null;
		try
		{
			cipher = Cipher.getInstance("AES");
			cipher.init(Cipher.ENCRYPT_MODE,key);
			retVal = cipher.doFinal(bytes);
			return retVal;
		}catch (NoSuchAlgorithmException e)
        {
		    if(_logger.isErrorEnabled()){
                _logger.error(e);
            }
		    throw new IccardException(e);
        } catch (NoSuchPaddingException e)
        {
            if(_logger.isErrorEnabled()){
                _logger.error(e);
            }
            throw new IccardException(e);
        } catch (InvalidKeyException e)
        {
            if(_logger.isErrorEnabled()){
                _logger.error(e);
            }
            throw new IccardException(e);
        } catch (IllegalBlockSizeException e)
        {
            if(_logger.isErrorEnabled()){
                _logger.error(e);
            }
            throw new IccardException(e);
        } catch (BadPaddingException e)
        {
            if(_logger.isErrorEnabled()){
                _logger.error(e);
            }
            throw new IccardException(e);
        }
		finally
		{
			cipher = null;
		}
	}
	
	public static void main(String[] args)
    {
        if(args == null || args.length != 2){
            System.out.println("the paramter for the crypter command is error! the command is the one of followed");
            System.out.println("java -cp . com.bcinfo.upp.util.AESCryptor -e encryptString");
            System.out.println("java -cp . com.bcinfo.upp.util.AESCryptor -d decryptString");
            System.exit(1);
        }
        
        if(args[0].equalsIgnoreCase("-e")){
            try
            {
                System.out.println(AESCryptor.encrypt(args[1]));
            }
            catch (IccardException e)
            {
                e.printStackTrace();
            }
        }else if(args[0].equalsIgnoreCase("-d")){
            try
            {
                System.out.println(AESCryptor.decrypt(args[1]));
            }
            catch (IccardException e)
            {
                e.printStackTrace();
            }
        }else {
            System.out.println("java -cp . com.bcinfo.upp.util.AESCryptor -e encryptString");
            System.out.println("java -cp . com.bcinfo.upp.util.AESCryptor -d decryptString");
        }
        
        
    }
}
